﻿#include "networkPacket .h"
#include "chessUtill.h"
#include <QIODevice>

QByteArray NetworkPacket::buildMatchRequest(QString playerId, 
    int gameTimeLimitMs, int stepTimeLimitMs) {
    QJsonObject data{
            {"player_id", playerId},
            {"time_control", QJsonObject{
                {"total", gameTimeLimitMs},
                {"step", stepTimeLimitMs}
            }}
    };

    return buildPacket(CommandType::MATCH_REQUEST, data);
}

QByteArray NetworkPacket::buildMoveRequest(QString roomId, QString playerId, QSharedPointer<Step> move) {
    QString moveStr = "move";
    if (((move->fromRow == -1) && (move->fromCol == -1)) ||
        (move->fromRow == move->toRow) && (move->fromCol == move->toCol)) {
        moveStr = "select";
    }
    
    QJsonObject data{
            {"room_id", roomId},
            {"player_id", playerId},
            {"action", moveStr},
            {"move", QJsonObject{
                {"from_x", move->fromRow},
                {"from_y", move->fromCol},
                {"to_x", move->toRow},
                {"to_y", move->toCol}
            }}
    };

    return buildPacket(CommandType::MOVE, data);
}

QByteArray NetworkPacket::buildPacket(CommandType cmd, const QJsonObject& data) {
    QByteArray jsonData = QJsonDocument(data).toJson();

    NetworkHeader header;
    header.magic = 0x88E4C5AA; ; // 魔数
    header.version = 0x01; // 协议版本
    header.algorithm = 0x00; // 0x00=JSON 0x01=Protobuf
    header.command = static_cast<uint8_t>(cmd); // 指令类型
    header.length = static_cast<uint32_t>(jsonData.size());

    QByteArray packet;
    packet.append(headerToSmallOrBigEndian(header, QDataStream::BigEndian));
    packet.append(jsonData);

    // 客户端发送前打印协议包
    qDebug() << "Packet hex:" << packet.toHex();

    return packet;
}

QByteArray NetworkPacket::headerToSmallOrBigEndian(const NetworkHeader& header, 
    QDataStream::ByteOrder order) {
    QByteArray headerByte;
	QDataStream stream(&headerByte, QIODevice::WriteOnly);
	stream.setByteOrder(order);
    stream << header.magic;
	stream << header.version;
	stream << header.algorithm;
	stream << header.command;
	stream << header.length;

    // 检查是否写入成功
    if (stream.status() != QDataStream::Ok) {
        qWarning() << "Failed to serialize NetworkHeader!";
        return QByteArray(); // 返回空数组表示错误
    }

    return headerByte;
}

